﻿#include "study09.h"
// C/C++ 标准库学习网站：https://legacy.cplusplus.com
// C/C++ 微软(Visual Studio)中文学习网站：https://learn.microsoft.com/zh-cn/cpp/cpp/?view=msvc-170
using namespace std; // 命名空间声明

class Base {
public:
	virtual const char* get_name() { return "Base"; }

	Base() { cout << "Base() Constructor" << endl; }

	virtual ~Base() { cout << "Base() Destructor" << endl; }
};

class Derived : public Base {
public:
	const char* get_name() { return "Derived"; }

	Derived() {
		data_str = new char[100];
		strcpy(data_str, "this is Derived class data_str acquiescent string");
		cout << "Derived() Constructor" << endl;
	}

	~Derived() { delete[] data_str; cout << "Derived() Destructor" << endl; }

	void print_data_str() { cout << "data_str = " << data_str << endl; }

private:
	//int* data_int  = new int(10); // 动态分配内存，10 为默认值
	char* data_str;
};

void test_virtual_destructor() {
	/*int* a = new int(10);
	cout << "a = " << *a << endl; */

	Base* b1 = new Base();
	delete b1; // 调用基类的析构函数，因为基类指针指向派生类对象，所以调用派生类的析构函数
	cout << "-----------------------------------------------------------\n";
	Derived* d1 = new Derived();
	d1->print_data_str();
	delete d1; // 调用派生类的析构函数，因为派生类继承了基类，所以会自动调用基类的析构函数
	cout << "-----------------------------------------------------------\n";
	Base* ploy1 = new Derived();  // 多态
	//ploy1->print_data_str(); // 基类指针就算多态也无法调用派生类的 print_data_str() 成员函数
	delete ploy1; // 默认只调用基类的析构函数，声明了虚析构函数，所以这里会调用派生类的析构函数
	cout << "-----------------------------------------------------------\n\n";
}

class AnotherDerived : public Base {
public:
	virtual const char* get_name() { return "AnotherDerived"; }

	AnotherDerived() { cout << "AnotherDerived() Constructor" << endl; }

	~AnotherDerived() { cout << "AnotherDerived() Destructor" << endl; }
};

void test_type_conversion() {
	float f1 = 3.1415926f;
	double d1 = (int)f1 + 0.5; // C 类型转换，将 float 转换为 double
	double d2 = reinterpret_cast<int&>(f1) + 0.5; // 重新解释类型转换，引用地址计算，然后强制转换为 double
	double d3 = static_cast<int>(f1) + 0.5;//静态类型转换，将 float 转为 int 计算后转为 double 同 C 语言一样
	cout << "d1 = " << d1 << ", d2 = " << d2 << ", d3 = " << d3 << endl
		<< "----------------------------------------------------\n";
	Derived* der1 = new Derived();
	Base* bs1 = der1; // 向上转型，将 Derived 指针转换为 Base 指针
	//AnotherDerived* ad1 = static_cast<AnotherDerived*>(bs1); // ok 这种是 C 风格，但是 ad1 不是 AnotherDerived 类型，只是 Derived 类型
	AnotherDerived* ad1 = dynamic_cast<AnotherDerived*>(bs1); // 运行时类型检查，将 Base 指针转换为 AnotherDerived 指针，失败返回 nullptr
	if (!ad1) // 因为 AnotherDerived 不是 Derived，所以 ad1 可能为 nullptr
		cout << "dynamic_cast Derived to AnotherDerived failed" << endl
		<< "----------------------------------------------------\n"; // 输出失败信息
	Derived* bs2 = dynamic_cast<Derived*>(bs1); // 运行时类型检查，将 Base 指针转换为 Derived 指针，失败返回 nullptr
	if (!bs2) // 因为 Derived 是 Base 的子类，所以 bs2 可能为 nullptr
		cout << "dynamic_cast Base to Derived failed" << endl; // 失败信息不被输出
	else { // 成功转换
		cout << "dynamic_cast Base to Derived succeed" << endl; // 输出成功信息
		delete bs2; // 释放内存
	}
}